package com.ys.service.sys.impl;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.annotation.Resource;

import org.springframework.context.ApplicationContext;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.ui.Model;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.ys.config.MenuId;
import com.ys.config.MyConfig;
import com.ys.constant.AppConstant;
import com.ys.dto.SubGridConfigDto;
import com.ys.entity.base.BaseEntity;
import com.ys.entity.shiro.LoginUser;
import com.ys.entity.sys.TsOrganizationInfo;
import com.ys.entity.sys.TsUserChange;
import com.ys.entity.sys.YsCol;
import com.ys.entity.sys.YsDict;
import com.ys.entity.sys.YsGridButton;
import com.ys.entity.sys.YsGridCol;
import com.ys.entity.sys.YsMenu;
import com.ys.entity.sys.YsMenuNo;
import com.ys.entity.sys.YsProcInst;
import com.ys.enume.flow.YsProcInstEnum;
import com.ys.enume.sys.YsColEnum;
import com.ys.enume.sys.YsGridButtonEnum;
import com.ys.enume.sys.YsRoleMenuEnum;
import com.ys.mapper.BaseMapper;
import com.ys.mapper.sys.SysMapper;
import com.ys.mapper.sys.YsMenuNoMapper;
import com.ys.service.sys.CommonApiService;
import com.ys.service.sys.CommonApiService.ToFormDto.FooterDto;
import com.ys.service.sys.CommonApiService.ToFormDto.RowDto;
import com.ys.service.sys.UploadService.UploadDto;
import com.ys.util.DateUtil;
import com.ys.util.FileUtilYs;
import com.ys.util.HttpUtilYs;
import com.ys.util.admin.SubGridUtil;
import com.ys.util.shiro.ShiroUtils;
import com.ys.vo.LayuiTableVoJA;
import com.ys.vo.R;
import com.ys.vo.W;

import cn.hutool.core.codec.Base64;

@Service("commonApiService")
public class CommonApiServiceImpl<E extends BaseEntity<E>> implements CommonApiService<E> {
	
	@Resource
	private SysMapper sysMapper;
	@Resource
	private YsMenuNoMapper ysMenuNoMapper;

	@Override
	public String getCommonNextBid(Long menuId) throws Exception {
		
		YsMenuNo entity = new YsMenuNo().setMenuId(menuId).queryFirst();
		if (entity == null) {
			throw new Exception("尚未设置单号格式");
		} else {
			
			String today = DateUtil.getYYYY_MM_DD(new Date());
			
			String preCode = entity.getPreCode();
			String connectCode = entity.getConnectCode();
			String middleCode = today.replace("-", "").substring(2);
			Integer currentNo = entity.getCurrentNo();
			if (entity.getCurrentDay().equals(today)) {
				
				// 当前日期是当天的，则序号+1
				entity.setCurrentNo(currentNo + 1);
				ysMenuNoMapper.update(entity);
				
				return preCode + connectCode + middleCode + connectCode + currentNo; 
			} else {
				
				// 当前日期不是当天的，则序号回归，日期回归当天
				currentNo = entity.getStartNo();
				entity.setCurrentNo(currentNo + 1)
					.setCurrentDay(today);
				ysMenuNoMapper.update(entity);

				return preCode + connectCode + middleCode + connectCode + currentNo; 
			}
		}
	}

	@Override
	public String getCommonNextUkey(Long menuId, String databaseFieldCode) throws Exception {
		
		String databaseTableName = MenuId.getTableName(menuId);
		if (databaseTableName == null || databaseTableName.length() == 0) {
			throw new Exception("尚未配置表名");
		}
		String preCode = MenuId.MENU_PRECODE.get(menuId);
		if (preCode == null || preCode.length() == 0) {
			throw new Exception("尚未配置前缀名");
		}
		Integer length = MenuId.MENU_UKEY_LENGTH.get(menuId);
		if (length == null) {
			throw new Exception("尚未配置字符串长度");
		}
		String num = sysMapper.getNextUkey(databaseTableName, databaseFieldCode);
		
		String result = "";
		for (int i = 0; i < length - num.length(); i++) {
			result += "0";
		}
		return preCode + result + num;
	}

	@Override
	public UploadDto uploadLocalToServer(String toFilePath) throws IOException {
		File file=new File(toFilePath);
		byte[] bytes = FileUtilYs.getBytesByFile(file);
		String fileBase64 = Base64.encode(bytes);

		JSONObject JO = new JSONObject();
		JO.put("base64Data", fileBase64);
		JO.put("sourceFileName", file.getName());
		
		String body = JO.toJSONString();
		String result = HttpUtilYs.sendPostJSON(MyConfig.getUrlFile() + "/api/outer/upload/uploadBase64", body);
		JSONObject resultJO = JSON.parseObject(result);
		String url = resultJO.getJSONObject("data").getString("url");
		return new UploadDto(url);
	}

	@Override
	@Transactional
	public LayuiTableVoJA searchLay(E entity) {
		
		Integer page = entity._ys_page;
		entity.setPage(page - 1);

		List<Map<String, Object>> listMap = entity.queryMap();
		Integer count = entity.count();
		LayuiTableVoJA vo = new LayuiTableVoJA();
		vo.setRowsByListMap(listMap);
        vo.setCount(count);
        return vo;
	}

	@Override
	@Transactional
	public R searchForDropdown(E entity) {

		List<Map<String, Object>> listMap = entity.queryMap();
        return R.ok(listMap);
	}

    @Override
    @Transactional
    public R deleteFalse(ApplicationContext ac, String className, Long id) throws Exception {
		
		@SuppressWarnings("unchecked")
		BaseMapper<E> mapperBean = (BaseMapper<E>) ac.getBean(className + "Mapper");
		mapperBean.deleteTrue(id);
        return R.ok();
    }

	@Override
	public String toAdd(Model model, E entity, Long menuId, Map<String, Object> extraParam, SubGridConfigDto subGridConfig) throws Exception {
		
		Map<String, Object> mapEntity = JSON.parseObject(JSON.toJSONString(entity));

		if (extraParam != null) {
			for(Map.Entry<String, Object> e : extraParam.entrySet()) {
				mapEntity.put(e.getKey(), e.getValue());
			}
		}
		
		// 制单人信息
		LoginUser loginUser = ShiroUtils.getLoginUser();
		
		YsMenu ysMenu = new YsMenu().setId(menuId).queryFirst();
		
		List<YsCol> listYsCol = new YsCol()
				.setMenuId(menuId)
				.setFormAddState(YsColEnum.FormAddState.YES.value)
				.setOrderby("A.SortNo asc")
				.queryList();

		List<ToFormDto.RowDto> rows = getFormRowsWhenAdd(listYsCol, mapEntity);

		String pathCommit = ysMenu.getPathCommitAdd();
		if (pathCommit == null || pathCommit.length() == 0) {
			return W.error(model, "提交路径尚未设置");
		}
		
		// 保存按钮
		ToFormDto.ButtonDto saveBtn = new ToFormDto.ButtonDto(1, pathCommit);
		// 删除按钮
		ToFormDto.ButtonDto deleteBtn = new ToFormDto.ButtonDto(0, null);
		// 流转通过按钮
		ToFormDto.ButtonDto flowPassBtn = new ToFormDto.ButtonDto(0, null);
		// 流转退回按钮
		ToFormDto.ButtonDto flowRefuseBtn = new ToFormDto.ButtonDto(0, null);
		// 流转驳回按钮
		ToFormDto.ButtonDto flowInitBtn = new ToFormDto.ButtonDto(0, null);
		// 流转记录按钮
		ToFormDto.ButtonDto flowLogBtn = new ToFormDto.ButtonDto(0, null);
		
		// 底部信息
		ToFormDto.FooterDto footer = this.getFooterForAdd(loginUser);
		
		String bid = null;
		ToFormDto dto = new ToFormDto(saveBtn, deleteBtn, flowPassBtn, flowRefuseBtn, flowInitBtn, flowLogBtn, bid, rows, footer, subGridConfig, AppConstant.URL_UPLOAD, mapEntity);
		model.addAttribute("dto", dto);
		model.addAttribute("js", "/static/js/form/" + menuId + ".js");
		
		if (!"dev".equals(MyConfig.getActive()) && !"test".equals(MyConfig.getActive()) && !"pro".equals(MyConfig.getActive())) {
			return "sys/common2/form";
		} else {
			return "sys/common/toAdd";
		}
	}

	@Override
	public String toEdit(Model model, Long id, E entity, Long menuId, Map<String, Object> extraParam, SubGridConfigDto subGridConfig) throws Exception {
		
		if (id == null) {
			return W.error(model, "ID不能为空");
		}
		
		
		Map<String, Object> valueMap = entity.where("A.Id = '" + id + "'").queryFirstMap();
		
		// 遍历额外参数对象
		if (extraParam != null) {
			for(Map.Entry<String, Object> e : extraParam.entrySet()) {
				valueMap.put(e.getKey(), e.getValue());
			}
		}
		
		YsMenu ysMenu = new YsMenu().setId(menuId).queryFirst();
		if (ysMenu == null) {
			return W.error(model, "此功能菜单不存在");
		}
		
		List<YsCol> listCol = new YsCol()
				.setMenuId(menuId)
				.setFormEditState(YsColEnum.FormEditState.YES.value)
				.setOrderby("A.SortNo asc")
				.queryList();
		
		List<ToFormDto.RowDto> rows = getFormRowsWhenEdit(listCol, valueMap);
		
		
		String pathCommit = ysMenu.getPathCommitEdit() + "?id=" + id;
		if (pathCommit == null || pathCommit.length() == 0) {
			return W.error(model, "提交路径尚未设置");
		}
		String bid = valueMap.containsKey("bid") ? valueMap.get("bid").toString() : null;
		
		YsProcInst ysProcInst = bid != null ? new YsProcInst().setBid(bid).queryFirst() : null;
		
		// 底部信息
		Long createChangeId = valueMap.containsKey("createChangeId") ? Long.parseLong(valueMap.get("createChangeId").toString()) : null;
		ToFormDto.FooterDto footer = this.getFooterForEdit(ysProcInst, createChangeId);
		
		
		// 保存按钮
		ToFormDto.ButtonDto saveBtn = this.getSaveBtn(2, ysMenu, ysProcInst, id);
		// 删除按钮
		ToFormDto.ButtonDto deleteBtn = this.getDeleteBtn(2, ysMenu, ysProcInst, id);
		// 流转通过按钮
		ToFormDto.ButtonDto flowPassBtn = this.getFlowPassBtn(2, ysMenu, ysProcInst, id);
		// 流转退回按钮
		ToFormDto.ButtonDto flowRefuseBtn = this.getFlowRefuseBtn(2, ysMenu, ysProcInst, id);
		// 流转驳回按钮
		ToFormDto.ButtonDto flowInitBtn = this.getFlowInitBtn(2, ysMenu, ysProcInst, id);
		// 流转记录按钮
		ToFormDto.ButtonDto flowLogBtn = this.getFlowLogBtn(2, ysMenu, ysProcInst, id);
		
		ToFormDto dto = new ToFormDto(saveBtn, deleteBtn, flowPassBtn, flowRefuseBtn, flowInitBtn, flowLogBtn, bid, rows, footer, subGridConfig, AppConstant.URL_UPLOAD, valueMap);
		model.addAttribute("dto", dto);
		model.addAttribute("js", "/static/js/form/" + menuId + ".js");
		
		if (!"dev".equals(MyConfig.getActive()) && !"test".equals(MyConfig.getActive()) && !"pro".equals(MyConfig.getActive())) {
			return "sys/common2/form";
		} else {
			return "sys/common/toEdit";
		}
	}

	@Override
	public ToFormDto getFormDto(String ids) throws Exception {
		
		if (ids == null || ids.length() == 0) {
			return null;
		}
		
		List<YsCol> listCol = new YsCol()
				.where("A.Id in (" + ids + ")")
				.setOrderby("A.SortNo asc")
				.queryList();
		
		List<ToFormDto.RowDto> rows = getFormRowsWhenGenerate(listCol);
		
		// 底部信息
		ToFormDto.FooterDto footer = null;
		
		// 保存按钮
		ToFormDto.ButtonDto saveBtn = new ToFormDto.ButtonDto(1, "/api/inter/xxx/xxx");
		// 删除按钮
		ToFormDto.ButtonDto deleteBtn = new ToFormDto.ButtonDto(0, null);
		// 流转通过按钮
		ToFormDto.ButtonDto flowPassBtn = new ToFormDto.ButtonDto(0, null);
		// 流转退回按钮
		ToFormDto.ButtonDto flowRefuseBtn = new ToFormDto.ButtonDto(0, null);
		// 流转驳回按钮
		ToFormDto.ButtonDto flowInitBtn = new ToFormDto.ButtonDto(0, null);
		// 流转记录按钮
		ToFormDto.ButtonDto flowLogBtn = new ToFormDto.ButtonDto(0, null);
		
//		// 保存按钮
//		ToFormDto.ButtonDto saveBtn = this.getSaveBtn(2, ysMenu, ysProcInst, id);
//		// 删除按钮
//		ToFormDto.ButtonDto deleteBtn = this.getDeleteBtn(2, ysMenu, ysProcInst, id);
//		// 流转通过按钮
//		ToFormDto.ButtonDto flowPassBtn = this.getFlowPassBtn(2, ysMenu, ysProcInst, id);
//		// 流转退回按钮
//		ToFormDto.ButtonDto flowRefuseBtn = this.getFlowRefuseBtn(2, ysMenu, ysProcInst, id);
//		// 流转记录按钮
//		ToFormDto.ButtonDto flowLogBtn = this.getFlowLogBtn(2, ysMenu, ysProcInst, id);
		
		String bid = null;
		SubGridConfigDto subGridConfig = null;
		ToFormDto dto = new ToFormDto(saveBtn, deleteBtn, flowPassBtn, flowRefuseBtn, flowInitBtn, flowLogBtn, bid, rows, footer, subGridConfig, AppConstant.URL_UPLOAD, new HashMap<String, Object>());
		return dto;
	}

	@Override
	public String toDetail(Model model, Long id, E entity, Long menuId, Map<String, Object> extraParam, SubGridConfigDto subGridConfig) throws Exception {
		
		if (id == null) {
			return W.error(model, "ID不能为空");
		}
		
		
		Map<String, Object> valueMap = new HashMap<String, Object>();
		
		// 遍历实体对象
		entity = entity.where("A.Id = '" + id + "'").queryFirst();
		JSONObject entityJO = JSON.parseObject(JSON.toJSONString(entity));
		entityJO.entrySet();
		for(Map.Entry<String, Object> e : entityJO.entrySet()) {
			valueMap.put(e.getKey(), e.getValue());
		}
		
		// 遍历额外参数对象
		if (extraParam != null) {
			for(Map.Entry<String, Object> e : extraParam.entrySet()) {
				valueMap.put(e.getKey(), e.getValue());
			}
		}
		
		YsMenu ysMenu = new YsMenu().setId(menuId).queryFirst();
		if (ysMenu == null) {
			return W.error(model, "此功能菜单不存在");
		}
		
		List<YsCol> listCol = new YsCol()
				.setMenuId(menuId)
				.setFormDetailState(YsColEnum.FormDetailState.YES.value)
				.setOrderby("A.SortNo asc")
				.queryList();
		
		List<ToFormDto.RowDto> rows = getFormRowsWhenDetail(listCol, valueMap);
		
		String bid = valueMap.containsKey("bid") ? valueMap.get("bid").toString() : null;
		
		YsProcInst ysProcInst = bid != null ? new YsProcInst().setBid(bid).queryFirst() : null;
		
		// 底部信息
		Long createChangeId = valueMap.containsKey("createChangeId") ? Long.parseLong(valueMap.get("createChangeId").toString()) : null;
		ToFormDto.FooterDto footer = this.getFooterForEdit(ysProcInst, createChangeId);
		
		
		// 保存按钮
		ToFormDto.ButtonDto saveBtn = null;
		// 删除按钮
		ToFormDto.ButtonDto deleteBtn = null;
		// 流转通过按钮
		ToFormDto.ButtonDto flowPassBtn = null;
		// 流转退回按钮
		ToFormDto.ButtonDto flowRefuseBtn = null;
		// 流转驳回按钮
		ToFormDto.ButtonDto flowInitBtn = null;
		// 流转记录按钮
		ToFormDto.ButtonDto flowLogBtn = null;
		
		ToFormDto dto = new ToFormDto(saveBtn, deleteBtn, flowPassBtn, flowRefuseBtn, flowInitBtn, flowLogBtn, bid, rows, footer, subGridConfig, null, valueMap);
		model.addAttribute("dto", dto);
		return "sys/common/toEdit";
	}
	
	/**
	 * 获取保存按钮
	 * @param usePlace 使用地方，1新增页2非新增页
	 * @return
	 */
	@Override
	public ToFormDto.ButtonDto getSaveBtn(Integer usePlace, YsMenu ysMenu, YsProcInst ysProcInst, Long id) {
		
		Integer state = 0;
		String pathCommit = null;
		if (usePlace == 1) {
			state = 1;
			pathCommit = ysMenu.getPathCommitAdd();
		} else if (usePlace == 2) {
			if (ysMenu.getFlowModelId().longValue() != 0L && ysProcInst.getStateFlow() == YsProcInstEnum.StateFlow.INIT.value) {
				state = 1;
			} else if (ysMenu.getFlowModelId().longValue() == 0L) {
				state = 1;
			}
			pathCommit = ysMenu.getPathCommitEdit() + "?id=" + id;
		}
		
		return new ToFormDto.ButtonDto(state, pathCommit);
	}
	
	/**
	 * 获取删除按钮
	 * @param usePlace 使用地方，1新增页2非新增页
	 * @return
	 */
	@Override
	public ToFormDto.ButtonDto getDeleteBtn(Integer usePlace, YsMenu ysMenu, YsProcInst ysProcInst, Long id) {
		
		Integer state = 0;
		String pathCommit = null;
		if (usePlace == 2) {
			if (ysMenu.getFlowModelId().longValue() != 0L && ysProcInst.getStateFlow() == YsProcInstEnum.StateFlow.INIT.value) {
				state = 1;
				pathCommit = ysMenu.getPathCommitDelete() + "?id=" + id;
			}
		}
		
		return new ToFormDto.ButtonDto(state, pathCommit);
	}
	
	/**
	 * 获取流转通过按钮
	 * @param usePlace 使用地方，1新增页2非新增页
	 * @return
	 */
	@Override
	public ToFormDto.ButtonDto getFlowPassBtn(Integer usePlace, YsMenu ysMenu, YsProcInst ysProcInst, Long id) {
		
		Integer state = 0;
		String pathCommit = null;
		if (usePlace == 2) {
			if (ysMenu.getFlowModelId().longValue() != 0L && ysProcInst.getStateFlow() != YsProcInstEnum.StateFlow.FINISH.value) {
				state = 1;
				pathCommit = ysMenu.getPathFlowPass() + "?id=" + id;
			}
		}
		
		return new ToFormDto.ButtonDto(state, pathCommit);
	}
	
	/**
	 * 获取流转退回按钮
	 * @param usePlace 使用地方，1新增页2非新增页
	 * @return
	 */
	@Override
	public ToFormDto.ButtonDto getFlowRefuseBtn(Integer usePlace, YsMenu ysMenu, YsProcInst ysProcInst, Long id) {
		
		Integer state = 0;
		String pathCommit = ysMenu.getPathFlowRefuse() + "?id=" + id;
		if (usePlace == 2) {
			if (ysMenu.getFlowModelId().longValue() != 0L && ysProcInst.getStateFlow() != YsProcInstEnum.StateFlow.FINISH.value) {
				state = 1;
				pathCommit = ysMenu.getPathFlowRefuse() + "?id=" + id;
			}
		}
		
		return new ToFormDto.ButtonDto(state, pathCommit);
	}
	
	/**
	 * 获取流转驳回按钮
	 * @param usePlace 使用地方，1新增页2非新增页
	 * @return
	 */
	@Override
	public ToFormDto.ButtonDto getFlowInitBtn(Integer usePlace, YsMenu ysMenu, YsProcInst ysProcInst, Long id) {
		
		Integer state = 0;
		String pathCommit = null;
		if (usePlace == 2) {
			if (ysMenu.getFlowModelId().longValue() != 0L && ysProcInst.getStateFlow() != YsProcInstEnum.StateFlow.FINISH.value) {
				state = 1;
				pathCommit = ysMenu.getPathFlowInit() + "?id=" + id;
			}
		}
		
		return new ToFormDto.ButtonDto(state, pathCommit);
	}
	
	/**
	 * 获取流转记录按钮
	 * @param usePlace 使用地方，1新增页2非新增页
	 * @return
	 */
	@Override
	public ToFormDto.ButtonDto getFlowLogBtn(Integer usePlace, YsMenu ysMenu, YsProcInst ysProcInst, Long id) {
		
		Integer state = 0;
		String pathCommit = null;
		if (usePlace == 2) {
			if (ysMenu.getFlowModelId().longValue() != 0L) {
				state = 1;
			}
		}
		
		return new ToFormDto.ButtonDto(state, pathCommit);
	}

	@Override
	public List<RowDto> getFormRowsWhenAdd(List<YsCol> listYsCol, Map<String, Object> mapEntity) throws Exception {

		List<ToFormDto.RowDto> rows = new ArrayList<ToFormDto.RowDto>();
		for (YsCol ysCol : listYsCol) {
			
			String code = ysCol.getCode();
			String name = ysCol.getName();
			String type = ysCol.getFormAddType();
			
			Integer required = ysCol.getFormAddRequired();
			Integer stateReadonly = ysCol.getFormAddReadonly();
			String dictKey = ysCol.getDictKeyBase();
			String modalKey = ysCol.getModalKey();
			String modalRelativeCode = ysCol.getModalRelativeCode();
			String modalValueCode = ysCol.getModalValueCode();
			Integer formLength = ysCol.getFormLength();
			Integer formHidden = ysCol.getFormAddHidden();
			String dropdownRequestPath = ysCol.getDropdownRequestPath();
			Integer multyFileSourceType = ysCol.getMultyFileSourceType();
			Long multyFileSourceId = mapEntity.containsKey("id") ? Long.parseLong(mapEntity.get("id").toString()) : null;
			String tip = ysCol.getFormTip();
			rows.add(new ToFormDto.RowDto(code, name, type, required, stateReadonly, dictKey, modalKey, modalRelativeCode, modalValueCode, formLength, formHidden, dropdownRequestPath, multyFileSourceType, multyFileSourceId, tip));
		}
		return rows;
	}

	@Override
	public List<RowDto> getFormRowsWhenEdit(List<YsCol> listYsCol, Map<String, Object> mapEntity) throws Exception {

		List<ToFormDto.RowDto> rows = new ArrayList<ToFormDto.RowDto>();
		for (YsCol ysCol : listYsCol) {
			
			String code = ysCol.getCode();
			String name = ysCol.getName();
			String type = ysCol.getFormEditType();
			
			Integer required = ysCol.getFormEditRequired();
			Integer stateReadonly = ysCol.getFormEditReadonly();
			String dictKey = ysCol.getDictKeyBase();
			String modalKey = ysCol.getModalKey();
			String modalRelativeCode = ysCol.getModalRelativeCode();
			String modalValueCode = ysCol.getModalValueCode();
			Integer formLength = ysCol.getFormLength();
			Integer formHidden = ysCol.getFormEditHidden();
			String dropdownRequestPath = ysCol.getDropdownRequestPath();
			Integer multyFileSourceType = ysCol.getMultyFileSourceType();
			Long multyFileSourceId = mapEntity.containsKey("id") ? Long.parseLong(mapEntity.get("id").toString()) : null;
			String tip = ysCol.getFormTip();
			rows.add(new ToFormDto.RowDto(code, name, type, required, stateReadonly, dictKey, modalKey, modalRelativeCode, modalValueCode, formLength, formHidden, dropdownRequestPath, multyFileSourceType, multyFileSourceId, tip));
		}
		return rows;
	}

	@Override
	public List<RowDto> getFormRowsWhenDetail(List<YsCol> listYsCol, Map<String, Object> mapEntity) throws Exception {

		List<ToFormDto.RowDto> rows = new ArrayList<ToFormDto.RowDto>();
		for (YsCol ysCol : listYsCol) {
			
			String code = ysCol.getCode();
			String name = ysCol.getName();
			String type = ysCol.getFormEditType();
			
			Integer required = 0;
			Integer stateReadonly = 1;
			String dictKey = ysCol.getDictKeyBase();
			String modalKey = null;
			String modalRelativeCode = null;
			String modalValueCode = null;
			Integer formLength = ysCol.getFormLength();
			Integer formHidden = 0;
			String dropdownRequestPath = null;
			Integer multyFileSourceType = ysCol.getMultyFileSourceType();
			Long multyFileSourceId = mapEntity.containsKey("id") ? Long.parseLong(mapEntity.get("id").toString()) : null;
			String tip = ysCol.getFormTip();
			rows.add(new ToFormDto.RowDto(code, name, type, required, stateReadonly, dictKey, modalKey, modalRelativeCode, modalValueCode, formLength, formHidden, dropdownRequestPath, multyFileSourceType, multyFileSourceId, tip));
		}
		return rows;
	}

	@Override
	public List<RowDto> getFormRowsWhenGenerate(List<YsCol> listYsCol) throws Exception {

		List<ToFormDto.RowDto> rows = new ArrayList<ToFormDto.RowDto>();
		for (YsCol ysCol : listYsCol) {
			
			String code = ysCol.getCode();
			String name = ysCol.getName();
			String type = ysCol.getFormEditType();
			
			Integer required = ysCol.getFormEditRequired();
			Integer stateReadonly = ysCol.getFormEditReadonly();
			String dictKey = ysCol.getDictKeyBase();
			String modalKey = ysCol.getModalKey();
			String modalRelativeCode = ysCol.getModalRelativeCode();
			String modalValueCode = ysCol.getModalValueCode();
			Integer formLength = ysCol.getFormLength();
			Integer formHidden = ysCol.getFormEditHidden();
			String dropdownRequestPath = ysCol.getDropdownRequestPath();
			Integer multyFileSourceType = ysCol.getMultyFileSourceType();
			Long multyFileSourceId = null;
			String tip = ysCol.getFormTip();
			rows.add(new ToFormDto.RowDto(code, name, type, required, stateReadonly, dictKey, modalKey, modalRelativeCode, modalValueCode, formLength, formHidden, dropdownRequestPath, multyFileSourceType, multyFileSourceId, tip));
		}
		return rows;
	}

	@Override
	public FooterDto getFooterForAdd(LoginUser loginUser) {
		
		Integer show = 1;
		String stateFlowName = "制单"; // 流程状态名称
		String createUserId = loginUser.getUserId() + "/" + loginUser.getUserName(); // 制单人工号/姓名
		String createDeptId = loginUser.getOrgName(); // 制单人部门
		String createRoleName = loginUser.getRoleName(); // 制单人岗位
		
		// 底部信息
		ToFormDto.FooterDto footer = new ToFormDto.FooterDto(show, stateFlowName, createUserId, createDeptId, createRoleName);
		
		return footer;
	}

	@Override
	public FooterDto getFooterForEdit(YsProcInst ysProcInst, Long createChangeId) {

		Integer show = 0;
		
		String stateFlowName = "制单"; // 流程状态名称
		String createUserId = "--"; // 制单人工号
		String createDeptId = "--"; // 制单人部门
		String createRoleName = "--"; // 制单人岗位
		if (createChangeId != null) {
			show = 1;
			
			TsUserChange tsUserChange = new TsUserChange().setId(createChangeId).queryFirst();

			if (ysProcInst == null){
				stateFlowName = "";
			}else {
				stateFlowName = YsProcInstEnum.StateFlow.getName(ysProcInst.getStateFlow()); // 流程状态名称
			}
			createUserId = tsUserChange.getUserId() + "/" + tsUserChange.getUserName(); // 制单人工号/姓名
			createDeptId = tsUserChange.getDeptName(); // 制单人部门
			createRoleName = tsUserChange.getRoleName(); // 制单人岗位
		}
		
		// 底部信息
		ToFormDto.FooterDto footer = new ToFormDto.FooterDto(show, stateFlowName, createUserId, createDeptId, createRoleName);
		return footer;
	}

	@Override
	public SubGridConfigDto getSubGrid(Long menuId, List<Map<String, Object>> sonlist) {
		if (menuId == null) {
			return null;
		}
		
		YsMenu ysMenu = new YsMenu().setId(menuId).queryFirst();
		if (ysMenu.getGridId() == null) {
			return null;
		}
		
		Long gridId = ysMenu.getGridId();
		
		// dictKey-List<SysDict>的MAP
		Map<String, List<YsDict>> KEY_LISTDICT_MAP = new HashMap<String, List<YsDict>>();
		List<YsDict> listYsDict = new YsDict()
				.where("A.DictKey in (select DictKeyBase from YS_GridCol where GridId = " + gridId + ")")
				.setOrderby("A.DictKey asc,A.SortNo asc")
				.queryList();
		for(YsDict ysDict : listYsDict) {
			String dictKey = ysDict.getDictKey();
			if (KEY_LISTDICT_MAP.containsKey(dictKey)) {
				KEY_LISTDICT_MAP.get(dictKey).add(ysDict);
			} else {
				List<YsDict> listValue = new ArrayList<YsDict>();
				listValue.add(ysDict);
				KEY_LISTDICT_MAP.put(dictKey, listValue);
			}
		}

		List<YsGridCol> listYsGridCol = new YsGridCol().setGridId(gridId)
				.setOrderby("A.SortNo asc")
				.queryList();
		List<SubGridConfigDto.ColGridDto> colGridArr = null;
		try {
			colGridArr = SubGridUtil.listColumn(listYsGridCol);
		} catch (Exception e) {
			e.printStackTrace();
		}
		
		// 按钮数组
		List<SubGridConfigDto.ButtonDto> buttonArr = new ArrayList<SubGridConfigDto.ButtonDto>();
		List<YsGridButton> listYsGridButton = new YsGridButton().setGridId(gridId).queryList();
		for(YsGridButton btn : listYsGridButton) {
			String name = btn.getName();
			String event = btn.getEvent();
			String icon = btn.getIcon();
			String style = YsGridButtonEnum.StyleType.getNameStyle(btn.getStyleType());
			buttonArr.add(new SubGridConfigDto.ButtonDto(name, event, icon, style));
		}
		
		// TPL脚本数组
		List<SubGridConfigDto.TempletDto> templetArr = SubGridUtil.listTemplets(listYsGridCol, KEY_LISTDICT_MAP);
		
		
		SubGridConfigDto subGrid = new SubGridConfigDto(gridId,
//				SubGridUtil.ColGridToString(colGridArr),
				colGridArr,
				buttonArr,
				templetArr,
				sonlist,
				AppConstant.URL_UPLOAD);
		
		return subGrid;
	}

	@Override
	public E dataAuth(Long menuId, E cond) {
		Long roleId = ShiroUtils.getRoleId();
		if (roleId.longValue() == 1L) {
			return cond;
		}
		Integer type = sysMapper.getTypeOfRoleMenu(roleId, menuId);
		if (type == YsRoleMenuEnum.Type.USER.value) {
			String userId = ShiroUtils.getUserId();
			Integer authType = type;
			List<YsCol> listYsCol = new YsCol().setMenuId(menuId).setAuthType(authType).queryList();
			for(YsCol ysCol : listYsCol) {
				String fieldCode = ysCol.getFrontConditionCode() != null && ysCol.getFrontConditionCode().length() > 0 ? ysCol.getFrontConditionCode() : ("A." + ysCol.getCode());
//				condSql = condSql + (fieldCode + " = '" + userId + "' and ");
				cond.where(fieldCode + " = '" + userId + "'");
			}
		} else if (type == YsRoleMenuEnum.Type.DEPT.value) {
			Long orgId = ShiroUtils.getOrgId();
			TsOrganizationInfo tsOrganizationInfo = new TsOrganizationInfo().setId(orgId).queryFirst();
			Integer authType = type;
			List<YsCol> listYsCol = new YsCol().setMenuId(menuId).setAuthType(authType).queryList();
			for(YsCol ysCol : listYsCol) {
				String fieldCode = ysCol.getFrontConditionCode() != null && ysCol.getFrontConditionCode().length() > 0 ? ysCol.getFrontConditionCode() : ("A." + ysCol.getCode());
				cond.addLeftJoin("TS_OrganizationInfo X_97 ON X_97.OrgId = " + fieldCode)
				.where("X_97.NodeLft >= " + tsOrganizationInfo.getNodeLft() + " AND X_97.NodeRgt <= " + tsOrganizationInfo.getNodeRgt());
			}
		} else if (type == YsRoleMenuEnum.Type.OPERATOR.value) {
			LoginUser loginUser = ShiroUtils.getLoginUser();
			Integer authType = type;
			List<YsCol> listYsCol = new YsCol().setMenuId(menuId).setAuthType(authType).queryList();
			for(YsCol ysCol : listYsCol) {
				String fieldCode = ysCol.getFrontConditionCode() != null && ysCol.getFrontConditionCode().length() > 0 ? ysCol.getFrontConditionCode() : ("A." + ysCol.getCode());
				cond.addLeftJoin("THR_OperateCompanyApply X_98 ON X_98.VGsbm = " + fieldCode)
					.addLeftJoin("TS_OperateOrg X_99 ON X_99.Id = X_98.OperateOrgId")
					.where("X_99.NodeLft >= " + loginUser.getOperateOrgNodeLft())
					.where("X_99.NodeRgt <= " + loginUser.getOperateOrgNodeRgt());
			}
		}
		
		return cond;
	}

//    @Override
//    @Transactional
//    public R deleteTrue(ApplicationContext ac, String className, Long id) {
//		
//		@SuppressWarnings("unchecked")
//		BaseMapper<E> mapperBean = (BaseMapper<E>) ac.getBean(className + "Mapper");
//		mapperBean.deleteTrue(id);
//        return R.ok();
//    }
}